home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-21 | 5.1 KB | 203 lines | [TEXT/ttxt] |
- -- <<<-
-
- -- plrpoint.sx
- -- by Howard Metzenberg, with help from Ross Nelson
- -- ScriptX sample code
- -- the PolarPoint and CartesianPoint classes
-
- -- this example demonstrates how to implement
- -- several of the common protocols for ScriptX objects
-
-
- module ObjectSystemKernelTest1 uses ScriptX end
- in module ObjectSystemKernelTest1
-
- class PolarPoint ()
- instance variables
- r, _theta
- instance methods
- method init self #rest args #key r: theta: -> (
- if not isAKindOf r Number do
- report invalidNumber r
- if r < 0 do
- report badParameter \
- #(r, init, self, "r must be > 0")
- if not isAKindOf theta Number do
- report invalidNumber theta
- apply nextMethod self args
- )
- method afterInit self #rest args #key r: theta: -> (
- apply nextMethod self args
- self.r := r
- self.theta := theta
- )
- method thetaGetter self -> self._theta
- -- normalizes theta between 0 and (2 * pi)
- method thetaSetter self value -> (
- local constant twoPI := (2 * pi)
- if value >= twoPI then
- self._theta := mod value twoPI
- else if value < 0 then
- self._theta := mod (twoPI + value) twoPI
- else
- self._theta := value
- )
- end
-
- class method newFrom self {class PolarPoint} other -> (
- if (isAKindOf other Point) then
- new self r:(sqrt (other.x * other.x + other.y * other.y)) \
- theta:(atan (other.y/other.x))
- else
- report cantCoerce #(other, self)
- )
-
- method morph self {class PolarPoint} cls style -> (
- if not isAKindOf cls Behavior do
- report badParameter \
- #(cls, morph, PolarPoint, "Expecting name of Class")
- if (isSub cls String) then
- "(" + (self.r as String) + " x " + (self.theta as String) + ")"
- else if (isSub cls Point) then
- new cls x:(self.r * (sin self.theta)) \
- y:(self.r * (cos self.theta))
- else
- report cantCoerce #(self, cls)
- )
-
- -- test coercion on the PolarPoint class
- object myPoint (Point) x:6, y:6 end
- object myPolarPoint (PolarPoint) r:(6 * sqrt 2), theta:(pi/4) end
- myPolarPoint.r
- myPolarPoint.theta
- global convertedPoint := myPoint as PolarPoint
- convertedPoint.r = (6 * sqrt 2)
- convertedPoint.theta = (pi / 4)
- myPolarPoint as String
-
- -- implement the Comparison protocol
- method isComparable self {class PolarPoint} other -> (
- if isAKindOf other Point or isAKindOf other PolarPoint then
- true
- else
- false
- )
-
- method localEqual self {class PolarPoint} other -> (
- local comparator
- if getClass other = PolarPoint then
- comparator := other
- else if isAKindOf other Point then
- comparator := other as PolarPoint
- else -- pass it on to RootObject, which reports exception
- nextMethod self other
- if self.r = comparator.r and self.theta = comparator.theta then
- return true
- else
- return false
- )
-
- method localLt self {class PolarPoint} other -> (
- local comparator := undefined
- if getClass other = PolarPoint then -- the same class
- comparator := other
- else if isAKindOf other Point then -- a comparable class
- comparator := other as PolarPoint
- else
- report generalError \
- "Cannot compare PolarPoint and %* objects." \
- (getClassName other)
- -- now do the actual comparison
- if self.r < comparator.r then
- return true
- else if self.r > comparator.r then
- return false
- else (
- if self.theta < comparator.theta then
- return true
- else
- return false
- )
- )
-
- --
- -- now create the CartesianPoint class
- -- and implement the Comparison protocol for it
- --
- class CartesianPoint (Point) end
-
- method isComparable self {class CartesianPoint} other -> (
- if isAKindOf other Point or isAKindOf other PolarPoint then
- true
- else
- nextMethod self other
- )
-
- method localEqual self {class CartesianPoint} other -> (
- if getClass other = PolarPoint then
- localEqual other self
- else if isAKindOf other Point then
- if self.x = other.x and self.y = other.y then
- true
- else
- false
- else
- nextMethod self other
- )
-
- method localLt self {class CartesianPoint} other -> (
- local comparator := undefined
- local cls := getClass other
- if cls = PolarPoint then
- localLt other self
- else if isAKindOf other Point then
- comparator := other as PolarPoint
- else
- report generalError "Cannot compare CartesianPoint and %*." cls
- if self.r < comparator.r then
- return true
- else if self.r > comparator.r then
- return false
- else (
- if self.theta < comparator.theta then
- return true
- else
- return false
- )
- )
-
- -- implement prin for PolarPoint
- --
- method prin self {class PolarPoint} formatStyle printStream -> (
- case formatStyle of
- @normal:(
- format printStream "[%n1, %n2] as PolarPoint" \
- #(self.r, self.theta)
- )
- @complete:(
- format printStream "[r=%c1, theta=%c2] as PolarPoint" \
- #(self.r, self.theta)
- )
- @unadorned:(
- format printStream "[%u1, %u2]" #(self.r, self.theta)
- )
- @debug:(
- (methodBinding RootObject prin) self @normal printStream
- writeString printStream ": ["
- writeString printStream (getClassName self.r)
- writeString printStream ": "
- writeString printStream (self.r as String)
- writeString printStream ", "
- writeString printStream (getClassName self.theta)
- writeString printStream ": "
- writeString printStream (self.theta as String)
- writeString printStream "]"
- )
- otherwise: (
- nextMethod self formatStyle printStream
- )
- end
- )
-
- -- >>>
-